package com.local.web.advice;

import com.local.cart.pojo.ShoppingCart;
import com.local.common.util.ResultUtil;
import com.local.web.constants.WebConstants;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.xml.transform.Result;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * ShoppingCart相关的切面方法
 */

@Component
@Aspect
public class ShoppingCartAdvice {

    /**
     * 查询用户购物车列表的切面方法：先从session里获取购物车列表；如果session里没有，则从db里查询
     * @param proceedingJoinPoint
     * @return
     */
    @Around("execution(public java.util.List<com.local.cart.pojo.ShoppingCart> com.local.web.service.ShoppingCartService.getListByUserId(..))")
    public List<ShoppingCart> getListByUserIdAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        HttpSession session = (HttpSession) args[0];
        Integer userId = (Integer) args[1];
        List<ShoppingCart> shoppingCartList = (List<ShoppingCart>) session.getAttribute(WebConstants.WEB_USER_CART_SESSION_KEY);
        if (Objects.nonNull(shoppingCartList)) {
            return shoppingCartList;
        } else {
            shoppingCartList = (List<ShoppingCart>) proceedingJoinPoint.proceed(args);
            if (Objects.nonNull(shoppingCartList)) {
                session.setAttribute(WebConstants.WEB_USER_CART_SESSION_KEY, shoppingCartList);
            }
        }
        return shoppingCartList;
    }


    /**
     * 加入购物车的切面方法：加入购物车之后，将数据加入到缓存
     * @param proceedingJoinPoint
     * @return
     */
    @Around("execution(public com.local.common.util.ResultUtil com.local.web.service.ShoppingCartService.addToCart(..))")
    public ResultUtil addToCartAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        HttpSession session = (HttpSession) args[0];
        ShoppingCart shoppingCart = (ShoppingCart) args[1];
        ResultUtil<ShoppingCart> resultUtil = (ResultUtil) proceedingJoinPoint.proceed(args);
        if (resultUtil.getCode() == 200) {
            List<ShoppingCart> shoppingCartList = (List<ShoppingCart>) session.getAttribute(WebConstants.WEB_USER_CART_SESSION_KEY);
            if (Objects.isNull(shoppingCartList)) {
                shoppingCartList = new ArrayList<>();
            }
            shoppingCart = resultUtil.getData();
            shoppingCartList.add(shoppingCart);
            session.removeAttribute(WebConstants.WEB_USER_CART_SESSION_KEY);
            session.setAttribute(WebConstants.WEB_USER_CART_SESSION_KEY, shoppingCartList);
        }

        return resultUtil;
    }


    /**
     * 删除购物车商品的切面方法：从DB中删除后，也要从缓存中删除
     * @param proceedingJoinPoint
     * @return
     */
    @Around("execution(public com.local.common.util.ResultUtil com.local.web.service.ShoppingCartService.deleteByCartItemId(..))")
    public ResultUtil deleteByCartItemIdAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        HttpSession session = (HttpSession) args[0];
        Integer cartItemId = (Integer) args[1];
        ResultUtil proceed = (ResultUtil) proceedingJoinPoint.proceed(args);
        if (proceed.getCode() == 200) {
            List<ShoppingCart> shoppingCartList = (List<ShoppingCart>) session.getAttribute(WebConstants.WEB_USER_CART_SESSION_KEY);
            if (Objects.nonNull(shoppingCartList) && shoppingCartList.size() > 0) {
                List<ShoppingCart> shoppingCartListResult = shoppingCartList.stream().filter(new Predicate<ShoppingCart>() {
                    @Override
                    public boolean test(ShoppingCart shoppingCart) {
                        if (cartItemId == shoppingCart.getCartItemId()) {
                            return false;
                        }
                        return true;
                    }
                }).collect(Collectors.toList());

                session.removeAttribute(WebConstants.WEB_USER_CART_SESSION_KEY);
                session.setAttribute(WebConstants.WEB_USER_CART_SESSION_KEY, shoppingCartListResult);
            }
        }

        return proceed;
    }


    /**
     * 修改购物车商品数量的切面方法：更新数据库之后，同时也更新缓存数据
     * @param proceedingJoinPoint
     * @return
     */
    @Around("execution(public com.local.common.util.ResultUtil com.local.web.service.ShoppingCartService.updateGoodsCount(..))")
    public ResultUtil updateGoodsCountAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        HttpSession session = (HttpSession) args[0];
        ShoppingCart shoppingCart = (ShoppingCart) args[1];
        ResultUtil proceed = (ResultUtil) proceedingJoinPoint.proceed(args);
        if (proceed.getCode() == 200) {
            List<ShoppingCart> shoppingCartList = (List<ShoppingCart>) session.getAttribute(WebConstants.WEB_USER_CART_SESSION_KEY);
            List<ShoppingCart> collect = shoppingCartList.stream().map(new Function<ShoppingCart, ShoppingCart>() {
                @Override
                public ShoppingCart apply(ShoppingCart shoppingCartItem) {
                    if (shoppingCartItem.getCartItemId() == shoppingCart.getCartItemId()) {
                        shoppingCartItem.setGoodsCount(shoppingCart.getGoodsCount());
                    }
                    return shoppingCartItem;
                }
            }).collect(Collectors.toList());
            session.removeAttribute(WebConstants.WEB_USER_CART_SESSION_KEY);
            session.setAttribute(WebConstants.WEB_USER_CART_SESSION_KEY, collect);
        }
        return proceed;
    }
}
